/**
 * 给定一个数组A，一个正整数M，问数组A中有多少个不同的子序列其LCM是M。
 * 首先将M做一个分解： M = p1 ^ k1 * p2 ^ k2 * ... pn ^ kn
 * M在1E16,因此n最多为13，分解的复杂度在O(sqrt(M))
 * 
 * 对每一个Ai，构造一个n位的二进制数：
 *     如果Ai不是M的因子则忽略
 *     如果Ai恰好含有kj个pj，则将第j位设置为1
 * 注意到如此构造出来的不同的二进制数最多有2^13-1个，而数组长度是1E5，因此中间必然有重复。
 * 因此首先要对A做一个计数，最后得到一个二进制数的多重集合，记作C。C的长度最多在2^13-1。
 * 
 * 于是原问题转化为了在C数组中选若干个数，令位或的结果为全1，问方案总数
 * 考虑采用容斥，首先计算出异或不为全1的方案数，则答案就是总数减去这个方案数。
 * 因此只需要计算不为全1的方案数。不为全1说明某些位上位或出来是0，这就要求参与运算的数，在这些位上全为0
 * 令 F[i] 表示位为零的指标数量。
 * 例如对数组：[000, 100, 010, 000, 001]
 * F[1] = 4， 第0位为0的数量是4个
 * F[2] = 4， 第1位为0的数量是4个
 * F[3] = 3， 第0位与第1位均为零的数量是3个
 * F[4] = 4， 第2位为零的数量是4个
 * F[5] = 3， 第0位与第2位均为零的数量是3个
 * F[6] = 3， ......
 * F[7] = 1， 三位全为零的数量是1个
 * 则不为全1的数量 = SIGMA{2 ^ F[i] - 1, i的二进制1的数量是奇数} - SIGMA{2 ^ F[i] - 1, i的二进制1的数量是偶数}
 * 
 * 实际实现的时候，不必显式的求出C数组，直接求F数组即可，然后容斥即可。
 * 似乎是3^K。
 * 79ms，远快于DP。
 * 如果先求C数组，再用暴力枚举，应该是K * 4^K，超时。
 */ 
#include <bits/stdc++.h>
#include <bits/extc++.h>
using namespace std;

using int128 = __int128_t;
using llt = long long;
llt const MOD = 998244353LL;
vector<llt> POW;

llt powerMod(llt a, llt n, llt mod){
    llt ret = 1;
    a %= mod;
    while(n){
        if(n & 1){
			ret = (int128)ret * a % mod;
			// (ret *= a) %= mod;
		} 
        n >>= 1;
        a = (int128)a * a % mod;
		// (a *= a) %= mod;
    }
    return ret;
}

/// 判断n是否为质数，直接用费尔马小定理，选择基底可以保证在64位整数下正确
bool MillerRabin(llt n, int repeat = 3){
    if(1 == n) return false;
    if(2 == n || 3 == n) return true;

	static const std::vector<long long> SEVEN = {
        2LL, 325LL, 9375LL, 28178LL, 450775LL, 9780504LL, 1795265022LL
	};

	static const std::vector<long long> TWELVE = {
		2, 3, 5, 7, 11, 13, 17, 19, 23, 29, 31, 37
	};


    llt d = n - 1;
	int r = 0;
    while(!(d & 1)) ++r, d >>= 1;

    const auto & vec = SEVEN;
	
	// while(repeat--){
    //     llt a = rand() % (n - 2) + 2;
	for(auto a : vec){
		if(a > n && 0 == (a %= n)) continue;
		llt x = powerMod(a, d, n);
		if(1 == x || n - 1 == x) continue;

		for(int i=1;i<r;++i){
            x = (int128)x * x % n;
			if(n - 1 == x) break;  			
		}
		if(n - 1 != x) return false;
	}
	return true;
}

/// 返回n的一个因子，有可能返回本身
/// 当n接近64位时，中间的乘法要转128位
llt PollardRho(llt n){
    llt s = 0, t = 0;
    llt c = rand() % (n - 1) + 1;
    int step = 0, goal = 1;
    llt val = 1;
    llt ans;
    for(goal=1;;goal<<=1,s=t,val=1){
        for(step=1;step<=goal;++step){
            t = ((int128)t * t % n + c) % n;
            val = (int128)val * abs(t - s) % n;
            if(0 == step % 127){
                if((ans = __gcd(val, n)) > 1){
                    return ans;
                }
            }               
        }
		if((ans = __gcd(val, n)) > 1){
            return ans;
        }
    }

    assert(0);
	return 0;
}

/// 找到所有的互异的质因子
void allFactors(llt n, vector<pair<llt, int>> & fac){
    fac.clear();
    function<void(llt)> __dfs = [&fac, &__dfs](llt x){
        if(1 == x) return;
        if(MillerRabin(x)) return (void)fac.emplace_back(x, 0);
		llt p;
		while((p = PollardRho(x)) >= x) ;
		while(0 == x % p) x /= p;
		__dfs(x); __dfs(p);
    };
	__dfs(n);
    sort(fac.begin(), fac.end());
    fac.erase(unique(fac.begin(), fac.end()), fac.end());
    return;
}

int N;
llt M;
vector<llt> A;
vector<pair<llt, int>> B;
vector<int> C;
map<llt, int> Cnt;

void dfs(int cnt, const vector<int> & vec, int pos, int f){
    if(pos == vec.size()) {
        if(0 == f) return; // 全0要忽略

        C[f] += cnt;
        return;
    };

    auto idx = vec[pos];
    dfs(cnt, vec, pos + 1, f);
    dfs(cnt, vec, pos + 1, f | (1 << idx));
    return;
}

llt proc(){
    POW.reserve(N + 1);
    POW.emplace_back(1LL);
    for(int i=1;i<=N;++i) POW.emplace_back(POW.back() * 2LL % MOD);

    if(1 == M){
        int c = 0;
        for(auto i : A)if(i == 1) c += 1;
        llt ans = POW[c];
        ans = (ans + MOD - 1) % MOD;
        return ans;
    }

    for(auto i : A) Cnt[i] += 1;

    allFactors(M, B);
    auto m = M;
    for(auto & p : B){
        while(m % p.first == 0) m /= p.first, ++p.second;
    }

    int total = 0;   
    int n = B.size();
    C.assign(1 << n, {});
    for(const auto & p : Cnt){
        auto t = p.first;
        if(M % t) continue;
        
        total += p.second;
        vector<int> vec;
        for(int i=0;i<n;++i){
            const auto & pp = B[i];
            auto factor = pp.first;
            if(t % factor == 0){
                int k = 0;
                while(0 == t % factor) t /= factor, k += 1;
                if(k != pp.second){
                    vec.emplace_back(i);
                }
            }else{
                vec.emplace_back(i);
            }
        }
#ifndef ONLINE_JUDGE
        cout << p.first << ":";
        for(auto i : vec) cout << " " << i;
        cout << endl;
#endif
        if(not vec.empty()) dfs(p.second, vec, 0, 0);
    }    
    llt ans = 0;
    for(int status=1;status<(1<<n);++status){
        const auto & p = C[status];

        if(__builtin_popcount(status) & 1){
            ans = (ans + POW[p] - 1) % MOD;
        }else{
            ans = (ans + 1 - POW[p]) % MOD;
        }
    }
    ans = (POW[total] - 1 - ans) % MOD;
    if(ans < 0) ans += MOD;
    return ans;
}

void work(){    
    cin >> N >> M;
    A.assign(N, {});
    for(auto & i : A) cin >> i;
    cout << proc() << endl;
    return;
}

int main() {
#ifndef ONLINE_JUDGE
    freopen("z.txt", "r", stdin);
#endif
    ios::sync_with_stdio(0); cin.tie(0); cout.tie(0);
    int nofkase = 1;
    // cin >> nofkase;
    while(nofkase--) work();
    return 0;
}